package com.java;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolExecutorAPI {
    static class RunnableSon implements Runnable {
        private String name;

        public RunnableSon(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return name;
        }

        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + "中的" + name + "正在运行");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 创建对象：参数不一定全部都需要手动配置，存在默认值
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2, // 核心线程数
                4, // 最大线程数
                10, // 最大空闲时间
                TimeUnit.SECONDS, // 时间单位
                new ArrayBlockingQueue<Runnable>(2), // 阻塞队列
                new ThreadFactory() { // 自定义线程工厂，通过Executors.defaultThreadFactory()可获得默认线程工厂
                    private final AtomicInteger id = new AtomicInteger(1);

                    @Override
                    public Thread newThread(Runnable r) { // 参数指被提交的任务
                        Thread thread = new Thread(r, "线程" + id.getAndIncrement());
                        System.out.println(thread.getName() + "在线程工厂内被创建");
                        return thread;
                    }
                },
                new RejectedExecutionHandler() { // 自定义拒绝策略，定义好的拒绝策略为为ThreadPoolExecutor的内部类
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // 参数指被拒绝的任务和该线程池
                        System.out.println(r.toString() + "通过拒绝策略被拒绝");
                    }
                }
        );

        // allowCoreThreadTimeOut：参数为true表明核心线程超过最大空闲实际也将被销毁
        executor.allowCoreThreadTimeOut(true);

        // prestartCoreThread：线程池预启动，启动核心线程使其空闲地等待工作
        // executor.prestartCoreThread();

        // prestartAllCoreThreads：线程池预启动，启动所有核心线程使它们空闲地等待工作
        executor.prestartAllCoreThreads();

        for (int i = 0; i < 10; i++) {
            Runnable runnable = new RunnableSon("任务" + (i + 1));

            // execute：提交任务到线程池，无返回值
            executor.execute(runnable);

            // submit：提交任务到线程池，返回值为Future实现类可获得任务执行结果
            // Future<?> future = executor.submit(callable);

            // invokeAll：提交多个任务到线程池，返回值为Future实现类集合可获得每个任务的执行结果
            // List<Future> invokeAll = executor.invokeAll(callables);

            // invokeAny：提交多个任务到线程池，返回值为最先执行完的任务的结果
            // Object invokeAny = executor.invokeAny(callables);
        }

        // shutdown：关闭线程池，无返回值。不再接受新任务，等正在运行的任务和阻塞队列中的任务运行结束后才真正开始关闭
        executor.shutdown();

        // shutdownNow：关闭线程池，返回值为未执行的任务列表。不再接受新任务，正在运行的任务的线程被中断且忽略阻塞队列中的任务，直接开始关闭
        // List<Runnable> runnables = executor.shutdownNow();
    }

    /**
     * 输出结果如下，每次运行的结果不同！共10个任务，其中6个运行成功，4个被拒绝
     * 线程1在线程工厂内被创建
     * 线程2在线程工厂内被创建
     * 线程3在线程工厂内被创建
     * 线程2中的任务1正在运行
     * 线程1中的任务2正在运行
     * 线程4在线程工厂内被创建
     * 任务7通过拒绝策略被拒绝
     * 线程3中的任务3正在运行
     * 任务8通过拒绝策略被拒绝
     * 任务9通过拒绝策略被拒绝
     * 任务10通过拒绝策略被拒绝
     * 线程4中的任务6正在运行
     * 线程3中的任务4正在运行
     * 线程2中的任务5正在运行
     */
}
